/*    file: G711EncoderContext.cpp
 *    desc:
 * 
 * created: 2018-03-14
 *  author: chuanjiang.zh@qq.com
 * company: 
 */

#include "G711EncoderContext.h"
#include "AVFramePtr.h"
#include "CLog.h"

using namespace av;

G711EncoderContext::G711EncoderContext():
	m_freq(8000),
	m_channels(1)
{
	m_buffer.ensure(1024 * 2);
}

G711EncoderContext::~G711EncoderContext()
{
	close();
}

int G711EncoderContext::open(int codec, int freq, int channels)
{
	m_freq = freq;
	m_channels = channels;

	m_profile.m_audioCodec = codec;
	m_profile.m_channels = 1;
	m_profile.m_samplerate = 8000;
	m_profile.m_sampleFormat = AV_SAMPLE_FMT_S16;

	return m_encoder.open(m_profile);
}

void G711EncoderContext::close()
{
	m_encoder.close();
}

int G711EncoderContext::encode(uint8_t* data, int length, int64_t pts, MPacket* pkt)
{
	//CLog::info("G711EncoderContext::encode. data:%p, length:%d, pts:%lld\n", data, length, pts);

	m_buffer.ensure(length);

	AVFramePtr frame(createAVFrame());
	frame->format = m_profile.m_sampleFormat;
	frame->pts = pts;

	frame->channels = m_channels;
	frame->sample_rate = m_freq;

	frame->nb_samples = length/2;

	if (frame->channels > 0)
	{
		frame->channel_layout = av_get_default_channel_layout(frame->channels);
	}

	{
		frame->data[0] = data;
		frame->linesize[0] = length;
	}

	AVPacket avpkt;
	av_init_packet(&avpkt);
	avpkt.data = m_buffer.data();
	avpkt.size = m_buffer.capacity();

	int rc = m_encoder.encode(frame.get(), &avpkt);

	if (rc == 0)
	{
		pkt->type = MTYPE_AUDIO;
		pkt->data = avpkt.data;
		pkt->size = avpkt.size;
		pkt->flags = avpkt.flags;
		pkt->pts = avpkt.pts;
	}

	return 0;
}


